/* made by Kamil Cukrowski.
 * licensed under Beerware license.
 * v1.0 */
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <sys/time.h>
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "common.h"

int debug = 0;

/* init and close log */
void common_open(const int level, const char *my_name) {
	debug = level;
	/* debug below or equal to 0 means putting messages to syslog */
	/* TODO syslog message levels - can be achieved with negativ debug numbers, or by debug > 100 for example */
	if (debug <= 0) { 
		openlog(my_name, LOG_PID, LOG_DAEMON);
		syslog(LOG_INFO, "Startup  succeeded.");
	}
}

void common_close(void) 
{
	if ( debug <= 0 ) 
		closelog();
}

/* Put something into the log */
void __attribute__((format(printf,6,7))) internal_logit
(const int level, const int type, const char *file, const int line, const char *function, const char *format, ...)
{
	char msg[4000];
	va_list va;

	/* do we need to do anything? */
	if ( debug < level) return;
	if ( debug <= 0 && type == LOG_DEBUG ) return;

	va_start (va, format);
	vsnprintf (msg, sizeof(msg), format, va);
	msg[sizeof(msg) - 1] = 0;
	/* debug = 0 means putting messages to syslog */
	if (debug > 0) {
		char time_str[20];
		struct timeval utc_time;
		struct tm tm_time;
		gettimeofday (&utc_time, NULL);
		localtime_r (&utc_time.tv_sec, &tm_time);
		strftime (time_str, sizeof(time_str), "%T", &tm_time);
		if (type <= LOG_ERR) {
			printf ("%s.%6u:(%s:%d %s): %s - error: %d:%s \n", 
				time_str, (unsigned)utc_time.tv_usec, file, line, function, msg, errno, strerror(errno));
		} else { 
			printf ("%s.%6u:(%s:%d %s): %s\n", 
				time_str, (unsigned)utc_time.tv_usec, file, line, function, msg);
		}
	} else {
		if (type <= LOG_ERR) {
			syslog(type, "(%s:%d %s): %s - error: %d:%s\n", 
				file, line, function, msg, errno, strerror(errno));
		} else {
			syslog(type, "(%s:%d %s): %s\n", 
				file, line, function, msg);
		}
	}
	va_end (va);
}

int daemonize(void) 
{
	int PID;
	PID = fork();
	switch ( PID ) {
	case 0:
		fclose(stderr);
		fclose(stdin);
		fclose(stdout);
		break;
	case -1:
		break;
	default:
		exit(0);
	}
	return(PID);
}

int daemonize_store_pid(const char *store_pid) 
{
	FILE *fd;
	int PID;
	PID = fork();
	switch ( PID ) {
	case 0:
		fclose(stderr);
		fclose(stdin);
		fclose(stdout);
		break;
	case -1:
		break;
	default:
		if ( (fd = fopen(store_pid,"w")) == NULL) {
			fclose(fd);
			debug=1;
			syslog(LOG_ERR, "Error opening pid file!");
			exit(-1);
		} else { 
			if ( fprintf(fd,"%d\n",PID) < 0 ) {
				fclose(fd);
				debug=1;
				syslog(LOG_ERR, "Error writing pid file!");
				exit(-1);
			}
			fclose(fd);
			exit(0);
		}
	}
	return(PID);
}
